function multiplyMatrices(matrixA, matrixB) {
    // 检查矩阵大小
    if (matrixA.length === 0 || matrixB.length === 0 || matrixA[0].length === 0 || matrixB[0].length === 0) {
        throw new Error('输入矩阵不能为空');
    }

    var m = matrixA.length;
    var n = matrixB[0].length;
    var p = matrixB.length;

    for (var i = 0; i < m; i++) {
        if (matrixA[i].length !== p) {
            throw new Error('矩阵A的列数与矩阵B的行数不匹配');
        }
    }

    for (var j = 0; j < p; j++) {
        if (matrixB[j].length !== n) {
            throw new Error('矩阵B的列数不匹配');
        }
    }

    var resultMatrix = [];

    for (var i = 0; i < m; i++) {
        var row = [];
        for (var j = 0; j < n; j++) {
            var sum = 0;
            for (var k = 0; k < p; k++) {
                sum += matrixA[i][k] * matrixB[k][j];
            }
            row.push(sum);
        }
        resultMatrix.push(row);
    }

    return resultMatrix;
}
function matrixPower(matrix, power) {
    // 确保矩阵是方阵
    if (matrix.length !== matrix[0].length) {
        throw new Error("矩阵必须是方阵。");
    }

    // 基本情况：当幂为0时，返回单位矩阵
    if (power === 0) {
        var identityMatrix = [];
        for (var i = 0; i < matrix.length; i++) {
            var row = [];
            for (var j = 0; j < matrix.length; j++) {
                row.push(i === j ? 1 : 0);
            }
            identityMatrix.push(row);
        }
        return identityMatrix;
    }

    // 递归情况：计算矩阵的幂
    if (power > 1) {
        var result = matrixPower(matrix, Math.floor(power / 2));
        result = multiplyMatrices(result, result);
        if (power % 2 === 1) {
            result = multiplyMatrices(result, matrix);
        }
        return result;
    }

    return matrix;
}
function inverseMatrix(matrix) {
    // Check if the matrix is square
    if (matrix.length !== matrix[0].length) {
        throw new Error('Inverse can only be calculated for square matrices.');
    }

    // Calculate the determinant of the matrix
    const det = determinant(matrix);

    // Check if the matrix is invertible (non-zero determinant)
    if (det === 0) {
        throw new Error('Matrix is not invertible.');
    }

    // Calculate the adjugate matrix
    const adjugate = calculateAdjugate(matrix);

    // Calculate the inverse matrix by dividing the adjugate by the determinant
    const inverse = scalarMultiply(adjugate, 1 / det);

    return inverse;
}

function determinant(matrix) {
    // Base case for 1x1 matrix
    if (matrix.length === 1 && matrix[0].length === 1) {
        return matrix[0][0];
    }

    // Base case for 2x2 matrix
    if (matrix.length === 2 && matrix[0].length === 2) {
        return (matrix[0][0] * matrix[1][1]) - (matrix[0][1] * matrix[1][0]);
    }

    let det = 0;

    for (let i = 0; i < matrix[0].length; i++) {
        const cofactor = (-1) ** i * matrix[0][i] * determinant(submatrix(matrix, 0, i));
        det += cofactor;
    }

    return det;
}

function submatrix(matrix, row, col) {
    return matrix.filter((_, i) => i !== row).map(row => row.filter((_, j) => j !== col));
}

function calculateAdjugate(matrix) {
    const adjugate = [];

    for (let i = 0; i < matrix.length; i++) {
        const row = [];

        for (let j = 0; j < matrix[i].length; j++) {
            const cofactor = (-1) ** (i + j) * determinant(submatrix(matrix, i, j));
            row.push(cofactor);
        }

        adjugate.push(row);
    }

    return transposeMatrix(adjugate);
}

function scalarMultiply(matrix, scalar) {
    return matrix.map(row => row.map(value => value * scalar));
}

function transposeMatrix(matrix) {
    if (matrix.length === 0) {
        return [];
    }

    const transposed = [];

    for (let i = 0; i < matrix[0].length; i++) {
        const row = [];

        for (let j = 0; j < matrix.length; j++) {
            row.push(matrix[j][i]);
        }

        transposed.push(row);
    }

    return transposed;
}

function evaluateExpression(ast, env) {
    if (ast instanceof Node) {
        const op = ast.op;
        const args = ast.args.map(arg => evaluateExpression(arg, env));

        if (op === 'power') {
            const base = args[0];
            const power = args[1];
            return matrixPower(base, power);
        } else if (op === 'multiply') {
            return multiplyMultipleMatrices(args);
        } else if (op === 'inverse') {
            const matrix = args[0];
            return inverseMatrix(matrix);
        } else if (op === 'transpose') {
            const matrix = args[0];
            return transposeMatrix(matrix);
        }
    } else if (typeof ast === 'string') {
        const variableName = ast;
        if (env.hasOwnProperty(variableName)) {
            return env[variableName];
        } else {
            throw new Error(`Variable "${variableName}" is not defined in the environment.`);
        }
    } else if (typeof ast === 'number') {
        return ast;
    } else if (Array.isArray(ast)) {
        return ast;
    }

    throw new Error('Invalid AST.');
}

function multiplyMultipleMatrices(matrices) {
    if (matrices.length < 2) {
        throw new Error('At least two matrices are required for the multiply operation.');
    }

    let result = matrices[0];

    for (let i = 1; i < matrices.length; i++) {
        result = multiplyMatrices(result, matrices[i]);
    }

    return result;
}